<!DOCTYPE html>
<html lang="en"><head>
<title>Introduction to Web Components</title>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8">
<link rel="stylesheet" href="spec.css" type="text/css">
<link rel="stylesheet" href="prettify.css" type="text/css">
<link rel="stylesheet" href="http://www.w3.org/StyleSheets/TR/W3C-WD" type="text/css">
</head>
<body>

<div class="head">


<div class="logo">
    <a href="http://www.w3.org/"><img width="72" height="48" src="//www.w3.org/Icons/w3c_home" alt="W3C"></a>
</div>

<h1>Introduction to Web Components</h1>
<h2 id="working-draft">W3C Working Draft 22 May 2012</h2>
<dl>
<dt>This version</dt>
    <dd><a href="http://www.w3.org/TR/2012/WD-components-intro-20120522/">http://www.w3.org/TR/2012/WD-components-intro-20120522/</a></dd>
<dt>Latest version</dt>
    <dd><a href="http://www.w3.org/TR/components-intro/">http://www.w3.org/TR/components-intro/</a></dd>
<dt>Latest editor's draft</dt>
    <dd><a href="http://dvcs.w3.org/hg/webcomponents/raw-file/tip/explainer/index.html">http://dvcs.w3.org/hg/webcomponents/raw-file/tip/explainer/index.html</a></dd>
<dt>Previous version</dt>
    <dd>none</dd>
<dt>Revision history</dt>
    <dd><a href="http://dvcs.w3.org/hg/webcomponents/log/tip/explainer/index.html">http://dvcs.w3.org/hg/webcomponents/log/tip/explainer/index.html</a></dd>
<dt>Participate</dt>
    <dd>Discuss on <a href="http://lists.w3.org/Archives/Public/public-webapps/">public-webapps@w3.org</a> (<a href="http://www.w3.org/2008/webapps/">Web Applications Working Group</a>)</dd>
    <dd><a href="https://www.w3.org/Bugs/Public/enter_bug.cgi?comment=&amp;blocked=14949&amp;short_desc=%5BExplainer%5D%3A%20&amp;product=WebAppsWG&amp;component=Component%20Model">File bugs</a> (w3.org's <a href="https://www.w3.org/Bugs/Public/">Bugzilla</a>)</dd>
<dt>Editors</dt>
    <dd class="vcard"><span class="fn">Dominic Cooney</span>, <span class="org">Google</span>, &lt;<a class="email" href="mailto:dglazkov@chromium.org">dominicc@google.com</a>&gt;</dd>
    <dd class="vcard"><span class="fn">Dimitri Glazkov</span>, <span class="org">Google</span>, &lt;<a class="email" href="mailto:dglazkov@chromium.org">dglazkov@chromium.org</a>&gt;</dd>
</dl>

<p class="copyright"><a href="http://www.w3.org/Consortium/Legal/ipr-notice#Copyright">Copyright</a> © 2012 <a href="http://www.w3.org/"><abbr title="World Wide Web Consortium">W3C</abbr></a><sup>®</sup> (<a href="http://www.csail.mit.edu/"><abbr title="Massachusetts Institute of Technology">MIT</abbr></a>, <a href="http://www.ercim.eu/"><abbr title="European Research Consortium for Informatics and Mathematics">ERCIM</abbr></a>, <a href="http://www.keio.ac.jp/">Keio</a>), All Rights Reserved. W3C <a href="http://www.w3.org/Consortium/Legal/ipr-notice#Legal_Disclaimer">liability</a>, <a href="http://www.w3.org/Consortium/Legal/ipr-notice#W3C_Trademarks">trademark</a> and <a href="http://www.w3.org/Consortium/Legal/copyright-documents">document use</a> rules apply.</p>

<hr>

<h2 id="abstract">Abstract</h2>

<p>This document is a non-normative reference, which aims to provide an overview of how Web Components work. It summarizes the normative information in the respective specifications in an easy-to-digest prose and illustration.</p>


<h2 id="status">Status of this Document</h2>

<p><em>This section describes the status of this document at the time of its publication. Other documents may supersede this document. A list of current <abbr title="World Wide Web Consortium">W3C</abbr> publications and the latest revision of this technical report can be found in the <a href="http://www.w3.org/TR/"><abbr title="World Wide Web Consortium">W3C</abbr> technical reports index</a> at http://www.w3.org/TR/.</em></p>

<p>This document was published by the <a href="http://www.w3.org/2008/webapps/">Web Applications Working Group</a> as a First Public Working Draft. If you wish to make comments regarding this document, please send them to <a href="mailto:public-webapps@w3.org">public-webapps@w3.org</a> (<a href="mailto:public-webapps-request@w3.org?subject=subscribe">subscribe</a>, <a href="http://lists.w3.org/Archives/Public/public-webapps/">archives</a>). All feedback is welcome.</p><p>Publication as a Working Draft does not imply endorsement by the <abbr title="World Wide Web Consortium">W3C</abbr> Membership. This is a draft document and may be updated, replaced or obsoleted by other documents at any time. It is inappropriate to cite this document as other than work in progress.</p>

<p>This document was produced by a group operating under the <a href="http://www.w3.org/Consortium/Patent-Policy-20040205/">5 February 2004 <abbr title="World Wide Web Consortium">W3C</abbr> Patent Policy</a>. This document is informative only. <abbr title="World Wide Web Consortium">W3C</abbr> maintains a <a href="http://www.w3.org/2004/01/pp-impl/42538/status" rel="disclosure">public list of any patent disclosures</a> made in connection with the deliverables of the group; that page also includes instructions for disclosing a patent. An individual who has actual knowledge of a patent which the individual believes contains <a href="http://www.w3.org/Consortium/Patent-Policy-20040205/#def-essential">Essential Claim(s)</a> must disclose the information in accordance with <a href="http://www.w3.org/Consortium/Patent-Policy-20040205/#sec-Disclosure">section 6 of the <abbr title="World Wide Web Consortium">W3C</abbr> Patent Policy</a>.</p>

</div>

<section class="toc">
<h2 id="toc">Table of Contents</h2>
<ol>
    <li><a href="#about"><span class="section">1</span> About this Document</a></li>
    <li><a href="#introduction"><span class="section">2</span> Introduction</a></li>
    <li><a href="#template-section"><span class="section">3</span> Templates</a></li>
    <li><a href="#decorator-section"><span class="section">4</span> Decorators</a>
    <ol>
        <li><a href="#events-in-decorators"><span class="section">4.1</span> Events in Decorators</a></li>
        <li><a href="#decorators-example"><span class="section">4.2</span> Decorators Example</a></li>
    </ol></li>
    <li><a href="#custom-element-section"><span class="section">5</span> Custom Elements</a>
    <ol>
        <li><a href="#presentation"><span class="section">5.1</span> Presentation</a></li>
        <li><a href="#using-custom-elements-in-markup"><span class="section">5.2</span> Using Custom Elements in Markup</a></li>
        <li><a href="#using-custom-elements-in-script"><span class="section">5.3</span> Using Custom Elements in Script</a></li>
        <li><a href="#element-upgrade"><span class="section">5.4</span> Element Upgrade</a></li>
        <li><a href="#lifecycle-methods"><span class="section">5.5</span> Lifecycle Methods</a></li>
        <li><a href="#extending-custom-elements"><span class="section">5.6</span> Extending Custom Elements</a></li>
        <li><a href="#error-handling"><span class="section">5.7</span> Error Handling</a></li>
    </ol></li>
    <li><a href="#shadow-dom-section"><span class="section">6</span> Shadow DOM</a>
    <ol>
        <li><a href="#content-and-shadow-elements"><span class="section">6.1</span> Content and Shadow Elements</a></li>
        <li><a href="#multiple-shadow-subtrees"><span class="section">6.2</span> Multiple Shadow Subtrees</a></li>
        <li><a href="#css-and-shadow-dom"><span class="section">6.3</span> CSS and Shadow DOM</a></li>
        <li><a href="#events"><span class="section">6.4</span> Events in Shadow DOM</a></li>
        <li><a href="#making-more-shadows"><span class="section">6.5</span> Making More Shadows</a></li>
    </ol></li>
    <li><a href="#decorators-vs-custom-elements"><span class="section">7</span> Decorators vs. Custom Elements</a></li>
    <li><a href="#external-custom-elements-and-decorators"><span class="section">8</span> External Custom Elements and Decorators</a></li>
    <li><a href="#isolation-confinement-and-encapsulation"><span class="section">9</span> Isolation, Confinement and Encapsulation</a></li>
    <li><a href="#example"><span class="section">10</span> Example</a></li>
    <li><a href="#appendix-a-interfaces">Appendix A. Interfaces</a></li>
    <li><a href="#appendix-b-html-elements">Appendix B. HTML Elements</a></li>
    <li><a href="#appendix-c-custom-element-constructor-properties">Appendix C. Custom Element Constructor Properties</a></li>
    <li><a href="#acknowledgements">Acknowledgements</a></li>
</ol>

</section>

<h2 id="about"><span class="section">1</span> About this Document</h2>

<p>As mentioned earlier, this document is a work in progress. It was initially written as a thought exercise to tie up all concepts, associated with the Web components into one coherent, non-normative narrative. Then, each concept will be refined and developed into a separate normative document, subsequently feeding back changes, concepts, and terms into this document. This iterative process is still continuing today, and produced the following specifications:</p>

<ul>
    <li><a href="http://www.w3.org/TR/shadow-dom/">Shadow DOM</a></li>
    <li><a href="http://dvcs.w3.org/hg/webcomponents/raw-file/tip/spec/templates/index.html">HTML Templates</a></li>
</ul>

<p>Once all information is extracted into the respective normative documents and this document is updated to accurately describe, as well as summarize the information in the normative documents, this document will be finalized and become the actual introduction for Web components.</p>

<h2 id="introduction"><span class="section">2</span> Introduction</h2>

<p>The component model for the Web (also known as Web Components) consists of four pieces designed to be used together to let web application authors define widgets with a level of visual richness not possible with CSS alone, and ease of composition and reuse not possible with script libraries today.</p>

<p>These pieces are:
</p><ul>
    <li><a href="#template-section">templates</a>, which define chunks of markup that are inert but can be activated for use later;</li>
    <li><a href="#decorator-section">decorators</a>, which apply templates to let CSS affect rich visual and behavioral changes to documents;</li>
    <li><a href="#custom-element-section">custom elements</a>, which let authors define their own elements, including new presentation and API, that can be used in HTML documents; and</li>
    <li><a href="#shadow-dom-section">shadow DOM</a> which defines how presentation and behavior of decorators and custom elements fit together in the DOM tree.</li>
</ul>

<p>Both decorators and custom elements are called <dfn>components</dfn>.</p>

<h2 id="template-section"><span class="section">3</span> Templates</h2>

<p>The <code id="#template-definition">&lt;template&gt;</code> element contains markup intended to be used later—by script or some other template-aware consumer (like <code>&lt;decorator&gt;</code> and <code>&lt;element&gt;</code> elements that are described later).</p>

<p>The content of the <code>&lt;template&gt;</code> element is parsed by the parser, but it is inert: scripts don't run, images aren't downloaded, and so on. The <code>&lt;template&gt;</code> element is not rendered.</p>

<p>In script the element has one property, <code>content</code>, which contains the inert DOM structure, defined by the template.</p>

<p>For example, a Web developer may want to define the DOM structure that is created multiple times in the document, and then create an instance of it anytime it's needed.</p>

<pre class="prettyprint"><code><span class="pln">
</span><span class="tag">&lt;template</span><span class="pln"> </span><span class="atn">id</span><span class="pun">=</span><span class="atv">"commentTemplate"</span><span class="tag">&gt;</span><span class="pln">
    </span><span class="tag">&lt;div&gt;</span><span class="pln">
        </span><span class="tag">&lt;img</span><span class="pln"> </span><span class="atn">src</span><span class="pun">=</span><span class="atv">""</span><span class="tag">&gt;</span><span class="pln">
        </span><span class="tag">&lt;div</span><span class="pln"> </span><span class="atn">class</span><span class="pun">=</span><span class="atv">"comment"</span><span class="tag">&gt;&lt;/div&gt;</span><span class="pln">
        …
    </span><span class="tag">&lt;/div&gt;</span><span class="pln">
</span><span class="tag">&lt;/template&gt;</span><span class="pln">

var t = document.querySelector("#commentTemplate");
// Populate content and img[src] values in the template.
// …
someElement.appendChild(t.content.cloneNode());</span></code></pre>

<p>Appending inert DOM to a document node makes it go "live", as if the DOM tree was just parsed from markup (setting innerHTML).</p>

<h2 id="decorator-section"><span class="section">4</span> Decorators</h2>

<p>A <dfn id="decorator-definition">decorator</dfn> is something that enhances or overrides the presentation of an existing element. Like all presentation aspects, the application of decorators is controlled by CSS. However, being able to specify the extra presentation using markup is unique to decorators.</p>

<p>The <code>&lt;decorator&gt;</code> element contains a <code>&lt;template&gt;</code> element, which specifies the markup to use for rendering the decoration.</p>

<pre class="prettyprint"><code><span class="pln">
</span><span class="tag">&lt;decorator</span><span class="pln"> </span><span class="atn">id</span><span class="pun">=</span><span class="atv">"fade-to-white"</span><span class="tag">&gt;</span><span class="pln">
    </span><span class="tag">&lt;template&gt;</span><span class="pln">
        </span><span class="tag">&lt;div</span><span class="pln"> </span><span class="atn">style</span><span class="pun">=</span><span class="atv">"</span><span class="pln">position</span><span class="pun">:</span><span class="pln"> relative</span><span class="pun">;</span><span class="atv">"</span><span class="tag">&gt;</span><span class="pln">
            </span><span class="tag">&lt;style</span><span class="pln"> </span><span class="atn">scoped</span><span class="tag">&gt;</span><span class="pln">
                </span><span class="com">#fog {</span><span class="pln">
                    position</span><span class="pun">:</span><span class="pln"> absolute</span><span class="pun">;</span><span class="pln">
                    left</span><span class="pun">:</span><span class="pln"> </span><span class="lit">0</span><span class="pun">;</span><span class="pln">
                    bottom</span><span class="pun">:</span><span class="pln"> </span><span class="lit">0</span><span class="pun">;</span><span class="pln">
                    right</span><span class="pun">:</span><span class="pln"> </span><span class="lit">0</span><span class="pun">;</span><span class="pln">
                    height</span><span class="pun">:</span><span class="pln"> </span><span class="lit">5em</span><span class="pun">;</span><span class="pln">
                    background</span><span class="pun">:</span><span class="pln"> linear</span><span class="pun">-</span><span class="pln">gradient</span><span class="pun">(</span><span class="pln">
                    bottom</span><span class="pun">,</span><span class="pln"> white </span><span class="lit">0</span><span class="pun">%,</span><span class="pln"> rgba</span><span class="pun">(</span><span class="lit">255</span><span class="pun">,</span><span class="pln"> </span><span class="lit">255</span><span class="pun">,</span><span class="pln"> </span><span class="lit">255</span><span class="pun">,</span><span class="pln"> </span><span class="lit">0</span><span class="pun">)</span><span class="pln"> </span><span class="lit">100</span><span class="pun">%);</span><span class="pln">
                </span><span class="pun">}</span><span class="pln">
            </span><span class="tag">&lt;/style&gt;</span><span class="pln">
            </span><span class="tag">&lt;content&gt;&lt;/content&gt;</span><span class="pln">
            </span><span class="tag">&lt;div</span><span class="pln"> </span><span class="atn">id</span><span class="pun">=</span><span class="atv">"fog"</span><span class="tag">&gt;&lt;/div&gt;</span><span class="pln">
        </span><span class="tag">&lt;/div&gt;</span><span class="pln">
    </span><span class="tag">&lt;/template&gt;</span><span class="pln">
</span><span class="tag">&lt;/decorator&gt;</span></code></pre>

<p>The <code><a href="http://www.w3.org/TR/shadow-dom/#content-element">&lt;content&gt;</a></code> element is the point where the content of the decorated element (element's children) should be inserted.</p>

<p>Decorators are applied using the <code>decorator</code> CSS property:</p>

<pre class="prettyprint"><code><span class="pln">
</span><span class="pun">.</span><span class="pln">poem </span><span class="pun">{</span><span class="pln">
    decorator</span><span class="pun">:</span><span class="pln"> url</span><span class="pun">(</span><span class="com">#fade-to-white);</span><span class="pln">
    font</span><span class="pun">-</span><span class="pln">variant</span><span class="pun">:</span><span class="pln"> small</span><span class="pun">-</span><span class="pln">caps</span><span class="pun">;</span><span class="pln">
</span><span class="pun">}</span></code></pre>

<p>This decorator and stylesheet would cause the following markup:</p>

<pre class="prettyprint"><code><span class="pln">
</span><span class="tag">&lt;div</span><span class="pln"> </span><span class="atn">class</span><span class="pun">=</span><span class="atv">"poem"</span><span class="tag">&gt;</span><span class="pln">
    Two roads diverged in a yellow wood,</span><span class="tag">&lt;br&gt;</span><span class="pln">
    …
</span><span class="tag">&lt;/div&gt;</span></code></pre>

<p>To be rendered as if it was this markup (omitting user agent styles for brevity):</p>

<pre class="prettyprint"><code><span class="pln">
</span><span class="tag">&lt;div</span><span class="pln"> </span><span class="atn">class</span><span class="pun">=</span><span class="atv">"poem"</span><span class="pln"> </span><span class="atn">style</span><span class="pun">=</span><span class="atv">"</span><span class="pln">font</span><span class="pun">-</span><span class="pln">variant</span><span class="pun">:</span><span class="pln"> small</span><span class="pun">-</span><span class="pln">caps</span><span class="pun">;</span><span class="atv">"</span><span class="tag">&gt;</span><span class="pln">
    </span><span class="tag">&lt;div</span><span class="pln"> </span><span class="atn">style</span><span class="pun">=</span><span class="atv">"</span><span class="pln">position</span><span class="pun">:</span><span class="pln"> relative</span><span class="pun">;</span><span class="atv">"</span><span class="tag">&gt;</span><span class="pln">
        Two roads diverged in a yellow wood,</span><span class="tag">&lt;br&gt;</span><span class="pln">
        …
        </span><span class="tag">&lt;div</span><span class="pln"> </span><span class="atn">style</span><span class="pun">=</span><span class="atv">"</span><span class="pln">position</span><span class="pun">:</span><span class="pln"> absolute</span><span class="pun">;</span><span class="pln"> left</span><span class="pun">:</span><span class="pln"> </span><span class="lit">0</span><span class="pun">;</span><span class="pln"> </span><span class="pun">…</span><span class="atv">"</span><span class="tag">&gt;&lt;/div&gt;</span><span class="pln">
    </span><span class="tag">&lt;/div&gt;</span><span class="pln">
</span><span class="tag">&lt;/div&gt;</span></code></pre>

<p>If the document changes so that the selector with the <code>decorator</code> property no longer matches—typically when a <a href="http://www.w3.org/TR/selectors/">selector</a> with the property no longer matches or the rule with this property was changed in the <a href="http://dev.w3.org/csswg/css-style-attr/">inline styles</a>, the decorator is unapplied, returning the rendering of the element back to the pre-decoration state.</p>

<p>Even though the <code>decorator</code> CSS property can point to any resource on the Web, the decorator will not be applied unless its definition is loaded by this document.</p>

<p>The markup that generates the presentation is limited to be purely presentational: it may never run script (including inline event hanlders) and it cannot be <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/editing.html#editing-0">editable</a>.</p>

<h3 id="events-in-decorators"><span class="section">4.1</span> Events in Decorators</h3>

<p>Decorators can also attach event handlers to implement interactivity. Because the decorators are transient, it is not useful for the decorator to attach event listeners to the nodes in the template or rely on any state, since it perishes any time decorator is applied or unapplied.</p>

<p>Instead, decorators register event listeners with an event controller. To register an event listener with an event controller, the template includes a <code>&lt;script&gt;</code> element. The script is run <em>once</em> when the <code>decorator</code> element is parsed or inserted into the document, or loaded as part of an external document.</p>

<figure>
    <img src="event-handler-registration.png">
    <figcaption>Fig. Event handler registration</figcaption>
</figure>

<p>The event controller is passed to the script in the <code>this</code> pointer.</p>

<pre class="prettyprint"><code><span class="pln">
</span><span class="tag">&lt;decorator</span><span class="pln"> </span><span class="atn">id</span><span class="pun">=</span><span class="atv">"decorator-event-demo"</span><span class="tag">&gt;</span><span class="pln">
    </span><span class="tag">&lt;script&gt;</span><span class="pln">
        </span><span class="kwd">function</span><span class="pln"> h</span><span class="pun">(</span><span class="pln">event</span><span class="pun">)</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
            alert</span><span class="pun">(</span><span class="pln">event</span><span class="pun">.</span><span class="pln">target</span><span class="pun">);</span><span class="pln">
        </span><span class="pun">}</span><span class="pln">
        </span><span class="kwd">this</span><span class="pun">.</span><span class="pln">listen</span><span class="pun">({</span><span class="pln">selector</span><span class="pun">:</span><span class="pln"> </span><span class="str">"#b"</span><span class="pun">,</span><span class="pln"> type</span><span class="pun">:</span><span class="pln"> </span><span class="str">"click"</span><span class="pun">,</span><span class="pln"> handler</span><span class="pun">:</span><span class="pln"> h</span><span class="pun">});</span><span class="pln">
    </span><span class="tag">&lt;/script&gt;</span><span class="pln">
    </span><span class="tag">&lt;template&gt;</span><span class="pln">
        </span><span class="tag">&lt;content&gt;&lt;/content&gt;</span><span class="pln">
        </span><span class="tag">&lt;button</span><span class="pln"> </span><span class="atn">id</span><span class="pun">=</span><span class="atv">"b"</span><span class="tag">&gt;</span><span class="pln">Bar</span><span class="tag">&lt;/button&gt;</span><span class="pln">
    </span><span class="tag">&lt;/template&gt;</span><span class="pln">
</span><span class="tag">&lt;/decorator&gt;</span></code></pre>

<p>The call to listen means that when the button with id <code>b</code> is clicked, the handler <code>h</code> is called.</p>

<p>The event controller routes events originating in any of the places that the decorator is applied to the event handler.</p>

<figure>
    <img src="event-routing-retargeting.png">
    <figcaption>Fig. Event routing and retargeting</figcaption>
</figure>

<p>When the event listener is called, the target of the event is the content that the decorator was applied to, and not content from the template. For example, given the decorator specified above, this content:</p>

<pre class="prettyprint"><code><span class="pln">
</span><span class="tag">&lt;span</span><span class="pln"> </span><span class="atn">style</span><span class="pun">=</span><span class="atv">"</span><span class="pln">decorator</span><span class="pun">:</span><span class="pln"> url</span><span class="pun">(</span><span class="com">#decorator-event-demo);</span><span class="atv">"</span><span class="tag">&gt;</span><span class="pln">Foo</span><span class="tag">&lt;/span&gt;</span></code></pre>

<p>Would be rendered like this:</p>

<pre class="prettyprint"><code><span class="pln">
</span><span class="typ">Foo</span><span class="pun">[</span><span class="typ">Bar</span><span class="pun">]</span></code></pre>

<p>Clicking on the button would show a dialog containing <code>[object HTMLSpanElement]</code>.</p>

<p>This retargeting is necessary because the decorator specifies presentation; it does not affect the structure of the document. Since it is in the document, the content the decorator is applied to is the target of the event.</p>

<p>Similarly, if script changes the content of the template later, this doesn't have any effect on the decorator, just like setting the <code>textContent</code> of a <code>&lt;script&gt;</code> element doesn't cause the script to execute again.</p>

<p>The decorators have no way to change the state of the decorating DOM tree, other than triggering application of a different decorator.</p>

<h3 id="decorators-example"><span class="section">4.2</span> Decorators Example</h3>

<p>Here is an example of how decorators could be used to implement a simple variant of the details element:</p>

<pre class="prettyprint"><code class="language-html"><span class="pln">
details {
    decorator: url(#details-closed);
}
details[open] {
    decorator: url(#details-open);
}

</span><span class="tag">&lt;decorator</span><span class="pln"> </span><span class="atn">id</span><span class="pun">=</span><span class="atv">"details-closed"</span><span class="tag">&gt;</span><span class="pln">
    </span><span class="tag">&lt;script&gt;</span><span class="pln">
        </span><span class="kwd">this</span><span class="pun">.</span><span class="pln">listen</span><span class="pun">({</span><span class="pln">
            selector</span><span class="pun">:</span><span class="pln"> </span><span class="str">"#summary"</span><span class="pun">,</span><span class="pln"> type</span><span class="pun">:</span><span class="pln"> </span><span class="str">"click"</span><span class="pun">,</span><span class="pln">
            handler</span><span class="pun">:</span><span class="pln"> </span><span class="kwd">function</span><span class="pln"> </span><span class="pun">(</span><span class="pln">event</span><span class="pun">)</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
                event</span><span class="pun">.</span><span class="pln">currentTarget</span><span class="pun">.</span><span class="pln">open </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">true</span><span class="pun">;</span><span class="pln">
            </span><span class="pun">}</span><span class="pln">
        </span><span class="pun">});</span><span class="pln">
    </span><span class="tag">&lt;/script&gt;</span><span class="pln">
    </span><span class="tag">&lt;template&gt;</span><span class="pln">
        </span><span class="tag">&lt;a</span><span class="pln"> </span><span class="atn">id</span><span class="pun">=</span><span class="atv">"summary"</span><span class="tag">&gt;</span><span class="pln">
            &amp;gt; </span><span class="tag">&lt;content</span><span class="pln"> </span><span class="atn">select</span><span class="pun">=</span><span class="atv">"summary:first-of-type"</span><span class="tag">&gt;&lt;/content&gt;</span><span class="pln">
        </span><span class="tag">&lt;/a&gt;</span><span class="pln">
    </span><span class="tag">&lt;/template&gt;</span><span class="pln">
</span><span class="tag">&lt;/decorator&gt;</span><span class="pln">

</span><span class="tag">&lt;decorator</span><span class="pln"> </span><span class="atn">id</span><span class="pun">=</span><span class="atv">"details-open"</span><span class="tag">&gt;</span><span class="pln">
    </span><span class="tag">&lt;script&gt;</span><span class="pln">
        </span><span class="kwd">this</span><span class="pun">.</span><span class="pln">listen</span><span class="pun">({</span><span class="pln">
            selector</span><span class="pun">:</span><span class="pln"> </span><span class="str">"#summary"</span><span class="pun">,</span><span class="pln"> type</span><span class="pun">:</span><span class="pln"> </span><span class="str">"click"</span><span class="pun">,</span><span class="pln">
            handler</span><span class="pun">:</span><span class="pln"> </span><span class="kwd">function</span><span class="pln"> </span><span class="pun">(</span><span class="pln">event</span><span class="pun">)</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
                event</span><span class="pun">.</span><span class="pln">currentTarget</span><span class="pun">.</span><span class="pln">open </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">false</span><span class="pun">;</span><span class="pln">
            </span><span class="pun">}</span><span class="pln">
        </span><span class="pun">});</span><span class="pln">
    </span><span class="tag">&lt;/script&gt;</span><span class="pln">
    </span><span class="tag">&lt;template&gt;</span><span class="pln">
        </span><span class="tag">&lt;a</span><span class="pln"> </span><span class="atn">id</span><span class="pun">=</span><span class="atv">"summary"</span><span class="tag">&gt;</span><span class="pln">
            V </span><span class="tag">&lt;content</span><span class="pln"> </span><span class="atn">select</span><span class="pun">=</span><span class="atv">"summary:first-of-type"</span><span class="tag">&gt;&lt;/content&gt;</span><span class="pln">
        </span><span class="tag">&lt;/a&gt;</span><span class="pln">
        </span><span class="tag">&lt;content&gt;&lt;/content&gt;</span><span class="pln">
    </span><span class="tag">&lt;/template&gt;</span><span class="pln">
</span><span class="tag">&lt;/decorator&gt;</span></code></pre>

<p>This uses two decorators. One presents the details view closed; the other presents the details view open. Each decorator uses an event handler to respond to clicks by toggling the open state of the element. The content element's select attribute will be explained in detail later.</p>

<h2 id="custom-element-section"><span class="section">5</span> Custom Elements</h2>

<p>Custom elements are new types of DOM elements that can be defined by authors.</p>

<p>Custom elements can define presentation aspects like decorators. Unlike a decorator, which can be applied or unapplied to a given element, the element's type is fixed. So custom elements can also define new state and behavior, which decorators can't do because of their ephemeral nature.</p>

<p>The element element defines a custom element. It specifies the type of element it's a refinement of using the extends attribute:</p>

<pre class="prettyprint"><code><span class="pln">
</span><span class="tag">&lt;element</span><span class="pln"> </span><span class="atn">extends</span><span class="pun">=</span><span class="atv">"button"</span><span class="pln"> </span><span class="atn">name</span><span class="pun">=</span><span class="atv">"x-fancybutton"</span><span class="tag">&gt;</span><span class="pln">
    …
</span><span class="tag">&lt;/element&gt;</span></code></pre>

<p>The extends attribute specifies the tag name of the kind of element this element is an extension of. Instances of the custom element will have the tag name specified here.</p>

<p>The name attribute specifies the name of the custom element, by which it will be referred to in markup. The naming space of the name is the same as element tag names, and to avoid collisions, the <code>x-</code> prefix is required for custom element value.</p>

<p>Different user agents interpret HTML elements differently, however all of their interpretations are guided by the semantics of HTML.</p>

<p>Because not all user agents support custom elements, authors should extend the HTML element that has the closest meaning to their new kind of element. For example, if they are defining a custom element that is interactive and responds to clicks by doing some action, they should extend button.</p>

<p>When there isn't a HTML element that is semantically close to their custom element authors should extend a semantically neutral element like span.</p>

<h3 id="presentation"><span class="section">5.1</span> Presentation</h3>

<p>A custom element may optionally include a template:

</p><pre class="prettyprint"><code><span class="pln">
</span><span class="tag">&lt;element</span><span class="pln"> </span><span class="atn">extends</span><span class="pun">=</span><span class="atv">"button"</span><span class="pln"> </span><span class="atn">name</span><span class="pun">=</span><span class="atv">"x-fancybutton"</span><span class="tag">&gt;</span><span class="pln">
    </span><span class="tag">&lt;template&gt;</span><span class="pln">
        </span><span class="tag">&lt;style</span><span class="pln"> </span><span class="atn">scoped</span><span class="tag">&gt;</span><span class="pln">
            </span><span class="pun">:</span><span class="pln">host </span><span class="pun">{</span><span class="pln"> display</span><span class="pun">:</span><span class="pln"> contents</span><span class="pun">;</span><span class="pln"> </span><span class="pun">}</span><span class="pln">
            div</span><span class="pun">.</span><span class="pln">fancy </span><span class="pun">{</span><span class="pln">
                </span><span class="pun">…</span><span class="pln">
            </span><span class="pun">}</span><span class="pln">
        </span><span class="tag">&lt;/style&gt;</span><span class="pln">
        </span><span class="tag">&lt;div</span><span class="pln"> </span><span class="atn">class</span><span class="pun">=</span><span class="atv">"fancy"</span><span class="tag">&gt;</span><span class="pln">
            </span><span class="tag">&lt;content&gt;&lt;/content&gt;</span><span class="pln">
            </span><span class="tag">&lt;div</span><span class="pln"> </span><span class="atn">id</span><span class="pun">=</span><span class="atv">"t"</span><span class="tag">&gt;&lt;/div&gt;</span><span class="pln">
            </span><span class="tag">&lt;div</span><span class="pln"> </span><span class="atn">id</span><span class="pun">=</span><span class="atv">"l"</span><span class="tag">&gt;&lt;/div&gt;</span><span class="pln">
            </span><span class="tag">&lt;div</span><span class="pln"> </span><span class="atn">id</span><span class="pun">=</span><span class="atv">"b"</span><span class="tag">&gt;&lt;/div&gt;</span><span class="pln">
            </span><span class="tag">&lt;div</span><span class="pln"> </span><span class="atn">id</span><span class="pun">=</span><span class="atv">"r"</span><span class="tag">&gt;&lt;/div&gt;</span><span class="pln">
        </span><span class="tag">&lt;/div&gt;</span><span class="pln">
    </span><span class="tag">&lt;/template&gt;</span><span class="pln">
</span><span class="tag">&lt;/element&gt;</span></code></pre>

<p>If a custom element includes a template, a copy of the template content is inserted into the custom element's shadow DOM by the generated constructor. Shadow DOM is described below.</p>

<h3 id="using-custom-elements-in-markup"><span class="section">5.2</span> Using Custom Elements in Markup</h3>

<p>Because custom elements use existing HTML tag names—<code>div</code>, <code>button</code>, <code>option</code>, and so on—we need to use an attribute to specify when an author intends to use a custom element. The attribute name is <code>is</code>, and its value is the name of a custom element. For example:</p>

<pre class="prettyprint"><code><span class="pln">
</span><span class="tag">&lt;element</span><span class="pln"> </span><span class="atn">extends</span><span class="pun">=</span><span class="atv">"button"</span><span class="pln"> </span><span class="atn">name</span><span class="pun">=</span><span class="atv">"x-fancybutton"</span><span class="tag">&gt;</span><span class="pln">  </span><span class="com">&lt;!-- definition --&gt;</span><span class="pln">
    …
</span><span class="tag">&lt;/element&gt;</span></code></pre>

<pre class="prettyprint"><code><span class="pln">
</span><span class="tag">&lt;button</span><span class="pln"> </span><span class="atn">is</span><span class="pun">=</span><span class="atv">"x-fancybutton"</span><span class="pln"> </span><span class="atn">onclick</span><span class="pun">=</span><span class="atv">"</span><span class="pln">showTimeClicked</span><span class="pun">(</span><span class="pln">event</span><span class="pun">);</span><span class="atv">"</span><span class="tag">&gt;</span><span class="pln">  </span><span class="com">&lt;!-- use --&gt;</span><span class="pln">
    Show time
</span><span class="tag">&lt;/button&gt;</span></code></pre>

<h3 id="using-custom-elements-in-script"><span class="section">5.3</span> Using Custom Elements in Script</h3>

<p>You can instantiate a custom element from script using the standard <code>document.createElement</code> facility:</p>

<pre class="prettyprint"><code><span class="pln">
</span><span class="kwd">var</span><span class="pln"> b </span><span class="pun">=</span><span class="pln"> document</span><span class="pun">.</span><span class="pln">createElement</span><span class="pun">(</span><span class="str">"x-fancybutton"</span><span class="pun">);</span><span class="pln">
alert</span><span class="pun">(</span><span class="pln">b</span><span class="pun">.</span><span class="pln">outerHTML</span><span class="pun">);</span><span class="pln"> </span><span class="com">// will display '&lt;button is="x-fancybutton"&gt;&lt;/button&gt;'</span></code></pre>

<p>Also, you can specify the <code>constructor</code> attribute on the <code>&lt;element&gt;</code> element to explicitly add a JavaScript property for the element constructor on the window object. That constructor can then be used to create instances of the custom element:</p>

<pre class="prettyprint"><code><span class="pln">
</span><span class="tag">&lt;element</span><span class="pln"> </span><span class="atn">extends</span><span class="pun">=</span><span class="atv">"button"</span><span class="pln"> </span><span class="atn">name</span><span class="pun">=</span><span class="atv">"x-fancybutton"</span><span class="pln"> </span><span class="atn">constructor</span><span class="pun">=</span><span class="atv">"FancyButton"</span><span class="tag">&gt;</span><span class="pln">
    …
</span><span class="tag">&lt;/element&gt;</span><span class="pln">

…

var b = new FancyButton();
document.body.appendChild(b);</span></code></pre>

<p>A custom element can expose API to script by putting properties on the constructor's prototype object, in a <code>&lt;script&gt;</code> that is nested inside the <code>&lt;element&gt;</code> element:</p>

<pre class="prettyprint"><code><span class="pln">
</span><span class="tag">&lt;element</span><span class="pln"> </span><span class="atn">extends</span><span class="pun">=</span><span class="atv">"button"</span><span class="pln"> </span><span class="atn">name</span><span class="pun">=</span><span class="atv">"x-fancybutton"</span><span class="pln"> </span><span class="atn">constructor</span><span class="pun">=</span><span class="atv">"FancyButton"</span><span class="tag">&gt;</span><span class="pln">
    …
    </span><span class="tag">&lt;script&gt;</span><span class="pln">
    </span><span class="typ">FancyButton</span><span class="pun">.</span><span class="pln">prototype</span><span class="pun">.</span><span class="pln">razzle </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">function</span><span class="pln"> </span><span class="pun">()</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
        </span><span class="pun">…</span><span class="pln">
    </span><span class="pun">};</span><span class="pln">
    </span><span class="typ">FancyButton</span><span class="pun">.</span><span class="pln">prototype</span><span class="pun">.</span><span class="pln">dazzle </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">function</span><span class="pln"> </span><span class="pun">()</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
        </span><span class="pun">…</span><span class="pln">
    </span><span class="pun">};</span><span class="pln">
    </span><span class="tag">&lt;/script&gt;</span><span class="pln">
</span><span class="tag">&lt;/element&gt;</span><span class="pln">

…

</span><span class="tag">&lt;script&gt;</span><span class="pln">
    </span><span class="kwd">var</span><span class="pln"> b </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">new</span><span class="pln"> </span><span class="typ">FancyButton</span><span class="pun">();</span><span class="pln">
    b</span><span class="pun">.</span><span class="pln">textContent </span><span class="pun">=</span><span class="pln"> </span><span class="str">"Show time"</span><span class="pun">;</span><span class="pln">
    document</span><span class="pun">.</span><span class="pln">body</span><span class="pun">.</span><span class="pln">appendChild</span><span class="pun">(</span><span class="pln">b</span><span class="pun">);</span><span class="pln">
    b</span><span class="pun">.</span><span class="pln">addEventListener</span><span class="pun">(</span><span class="str">"click"</span><span class="pun">,</span><span class="pln"> </span><span class="kwd">function</span><span class="pln"> </span><span class="pun">(</span><span class="pln">event</span><span class="pun">)</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
        event</span><span class="pun">.</span><span class="pln">target</span><span class="pun">.</span><span class="pln">dazzle</span><span class="pun">();</span><span class="pln">
    </span><span class="pun">});</span><span class="pln">
    b</span><span class="pun">.</span><span class="pln">razzle</span><span class="pun">();</span><span class="pln">
</span><span class="tag">&lt;/script&gt;</span></code></pre>

<p>In order to provide graceful fallback behavior, the this pointer within the <code>&lt;script&gt;</code> element points to parent HTMLElementElement instance:</p>

<pre class="prettyprint"><code><span class="pln">
</span><span class="tag">&lt;element</span><span class="pln"> </span><span class="atn">extends</span><span class="pun">=</span><span class="atv">"table"</span><span class="pln"> </span><span class="atn">name</span><span class="pun">=</span><span class="atv">"x-chart"</span><span class="pln"> </span><span class="atn">constructor</span><span class="pun">=</span><span class="atv">"Chart"</span><span class="tag">&gt;</span><span class="pln">
    </span><span class="tag">&lt;script&gt;</span><span class="pln">
        </span><span class="kwd">if</span><span class="pln"> </span><span class="pun">(</span><span class="kwd">this</span><span class="pln"> </span><span class="pun">===</span><span class="pln"> window</span><span class="pun">)</span><span class="pln">
            </span><span class="com">// Use polyfills to emulate custom elements.</span><span class="pln">
            </span><span class="com">// …</span><span class="pln">
        </span><span class="kwd">else</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
            </span><span class="com">// …</span><span class="pln">
        </span><span class="pun">}</span><span class="pln">
    </span><span class="tag">&lt;/script&gt;</span><span class="pln">
</span><span class="tag">&lt;/element&gt;</span></code></pre>

<p>Mechanically, the code inside of the <code>&lt;script&gt;</code> element when it is a child of either <code>&lt;element&gt;</code> or <code>&lt;decorator&gt;</code> elements is executed like this:</p>

<pre class="prettyprint"><code><span class="pln">
</span><span class="pun">(</span><span class="kwd">function</span><span class="pun">()</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
    </span><span class="com">// code goes here.</span><span class="pln">
</span><span class="pun">}).</span><span class="pln">call</span><span class="pun">(</span><span class="pln">parentInstance</span><span class="pun">);</span></code></pre>

<p>In situations where having constructors on window object is undesirable, the custom element author can use <code>generatedConstructor</code> property of the <code>HTMLElementElement</code>:</p>

<pre class="prettyprint"><code><span class="pln">
</span><span class="tag">&lt;element</span><span class="pln"> </span><span class="atn">extends</span><span class="pun">=</span><span class="atv">"table"</span><span class="pln"> </span><span class="atn">name</span><span class="pun">=</span><span class="atv">"x-chart"</span><span class="tag">&gt;</span><span class="pln">
    </span><span class="tag">&lt;script&gt;</span><span class="pln">
        </span><span class="com">// …</span><span class="pln">
        </span><span class="kwd">var</span><span class="pln"> </span><span class="typ">Chart</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">this</span><span class="pun">.</span><span class="pln">generatedConstructor</span><span class="pun">;</span><span class="pln">
        </span><span class="typ">Chart</span><span class="pun">.</span><span class="pln">prototype</span><span class="pun">.</span><span class="pln">shizzle </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">function</span><span class="pun">()</span><span class="pln"> </span><span class="pun">{</span><span class="pln"> </span><span class="com">/* … */</span><span class="pln"> </span><span class="pun">};</span><span class="pln">
        </span><span class="com">// …</span><span class="pln">
    </span><span class="tag">&lt;/script&gt;</span><span class="pln">
</span><span class="tag">&lt;/element&gt;</span></code></pre>

<p>One cannot create a custom element by setting an <code>is</code> attribute on an existing DOM element. Doing so will result in a no-op:</p>

<pre class="prettyprint"><code><span class="pln">
</span><span class="kwd">var</span><span class="pln"> div </span><span class="pun">=</span><span class="pln"> document</span><span class="pun">.</span><span class="pln">createElement</span><span class="pun">(</span><span class="str">"div"</span><span class="pun">);</span><span class="pln">
div</span><span class="pun">.</span><span class="pln">setAttribute</span><span class="pun">(</span><span class="str">"is"</span><span class="pun">,</span><span class="pln"> </span><span class="str">"foo"</span><span class="pun">);</span><span class="pln">
alert</span><span class="pun">(</span><span class="pln">div</span><span class="pun">.</span><span class="kwd">is</span><span class="pun">);</span><span class="pln"> </span><span class="com">// displays null</span><span class="pln">
alert</span><span class="pun">(</span><span class="pln">div</span><span class="pun">.</span><span class="pln">outerHTML</span><span class="pun">);</span><span class="pln"> </span><span class="com">// displays &lt;div&gt;&lt;/div&gt;</span></code></pre>

<h3 id="element-upgrade"><span class="section">5.4</span> Element Upgrade</h3>

<p>As the definition of a custom element is loaded, each element with the <code>is</code> attribute set to the name of that custom element is upgraded to the custom element. The upgrade process should be perceptually equivalent to removal of the element from the document and its replacement by the custom element instance.</p>

<p>As each element is replaced, a non-bubbling, non-cancellable event is dispatched to the element that has been removed. Scripts that want to delay interacting with part of a document until the custom elements are present can listen to this event:</p>

<pre class="prettyprint"><code><span class="pln">
</span><span class="kwd">function</span><span class="pln"> showTimeClicked</span><span class="pun">(</span><span class="kwd">event</span><span class="pun">)</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
    </span><span class="com">// event.target may be an HTMLButtonElement or a FancyButton</span><span class="pln">

    </span><span class="kwd">if</span><span class="pln"> </span><span class="pun">(!</span><span class="kwd">event</span><span class="pun">.</span><span class="pln">target</span><span class="pun">.</span><span class="pln">razzle</span><span class="pun">)</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
        </span><span class="com">// razzle, part of the FancyButton API, is missing</span><span class="pln">
        </span><span class="com">// so upgrade has not happened yet</span><span class="pln">
        </span><span class="kwd">event</span><span class="pun">.</span><span class="pln">target</span><span class="pun">.</span><span class="pln">addEventListener</span><span class="pun">(</span><span class="str">'upgrade'</span><span class="pun">,</span><span class="pln"> </span><span class="kwd">function</span><span class="pln"> </span><span class="pun">(</span><span class="pln">upgradeEvent</span><span class="pun">)</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
            showTime</span><span class="pun">(</span><span class="pln">upgradeEvent</span><span class="pun">.</span><span class="pln">replacement</span><span class="pun">);</span><span class="pln">
        </span><span class="pun">});</span><span class="pln">
        </span><span class="kwd">return</span><span class="pun">;</span><span class="pln">
    </span><span class="pun">}</span><span class="pln">

    showTime</span><span class="pun">(</span><span class="kwd">event</span><span class="pun">.</span><span class="pln">target</span><span class="pun">);</span><span class="pln">
</span><span class="pun">}</span><span class="pln">

</span><span class="kwd">function</span><span class="pln"> showTime</span><span class="pun">(</span><span class="pln">b</span><span class="pun">)</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
    </span><span class="com">// b is FancyButton</span><span class="pln">
</span><span class="pun">}</span></code></pre>

<p>Authors who want to avoid the flash of unstyled content can use CSS to change the presentation of the ordinary element until the custom element is loaded.</p>

<h3 id="lifecycle-methods"><span class="section">5.5</span> Lifecycle Methods</h3>

<p>A custom element can optionally subscribe to these four lifecycle callbacks:</p>
<ul>
    <li><code>created</code>—called by the generated constructor, passing a <code>ShadowRoot</code> instance, created from the <code>&lt;template&gt;</code> element or <code>null</code>, if there was no <code>&lt;template&gt;</code> element in the declaration.
    </li><li><code>attributeChanged</code>—called whenever an attribute of the element is changed. The arguments are the name, old value and the new value.
    </li><li><code>inserted</code>—called after the custom element is inserted into the tree. If a custom element needs to start loading resources or start timers, it can do that in this method.
    </li><li><code>removed</code>—called after the custom element is removed from the tree. A custom element can stop timers that it does not need when it is not in the tree.
</li></ul>

<p>The callbacks are invoked with this as the instance element.</p>

<p>The inserted and removed callbacks may be called multiple times if the element as the element is inserted and removed from the tree.</p>

<p>You can subscribe to these callbacks by invoking <code>HTMLElementElement.lifecycle</code> method:</p>

<pre class="prettyprint"><code><span class="pln">
</span><span class="tag">&lt;element</span><span class="pln"> </span><span class="atn">extends</span><span class="pun">=</span><span class="atv">"time"</span><span class="pln"> </span><span class="atn">name</span><span class="pun">=</span><span class="atv">"x-clock"</span><span class="tag">&gt;</span><span class="pln">
</span><span class="tag">&lt;script&gt;</span><span class="pln">
</span><span class="com">// …</span><span class="pln">

        </span><span class="kwd">this</span><span class="pun">.</span><span class="pln">lifecycle</span><span class="pun">({</span><span class="pln">
            inserted</span><span class="pun">:</span><span class="pln"> </span><span class="kwd">function</span><span class="pun">()</span><span class="pln"> </span><span class="pun">{</span><span class="pln"> </span><span class="kwd">this</span><span class="pun">.</span><span class="pln">startUpdatingClock</span><span class="pun">();</span><span class="pln"> </span><span class="pun">},</span><span class="pln">
            removed</span><span class="pun">:</span><span class="pln"> </span><span class="kwd">function</span><span class="pun">()</span><span class="pln"> </span><span class="pun">{</span><span class="pln"> </span><span class="kwd">this</span><span class="pun">.</span><span class="pln">stopUpdatingClock</span><span class="pun">();</span><span class="pln"> </span><span class="pun">}</span><span class="pln">
        </span><span class="pun">});</span><span class="pln">

</span><span class="com">// …</span><span class="pln">
</span><span class="tag">&lt;/script&gt;</span><span class="pln">
</span><span class="tag">&lt;/element&gt;</span></code></pre>

<h3 id="extending-custom-elements"><span class="section">5.6</span> Extending Custom Elements</h3>

<p>In addition to HTML elements, you can also extend a custom element by specifying the custom element's name as the value of the extends attribute in the <code>&lt;element&gt;</code> element:</p>

<pre class="prettyprint"><code><span class="pln">
</span><span class="tag">&lt;element</span><span class="pln"> </span><span class="atn">extends</span><span class="pun">=</span><span class="atv">"x-clock"</span><span class="pln"> </span><span class="atn">name</span><span class="pun">=</span><span class="atv">"x-grandfatherclock"</span><span class="tag">&gt;</span><span class="pln">
    …
</span><span class="tag">&lt;/element&gt;</span></code></pre>

<h3 id="error-handling"><span class="section">5.7</span> Error Handling</h3>

<p>There are several opportunities for error when setting up custom elements:</p>
<ul>
    <li>The tag name of the element does not match the value of the <code>extends</code> attribute of the custom element, eg. <code>&lt;div is="x-fancybutton"&gt;</code>, but <code>&lt;element name="x-fancybutton" extends="button"&gt;</code>. In this case, the is attribute is thrown away while parsing.</li>
    <li>The value of the <code>is</code> attribute does not correspond to any currently defined element. This situation is treated as if the definitions hasn't been loaded yet, and the element will be upgraded as soon as the definition arrives.</li>
    <li>The value of the <code>extends</code> attribute does not correspond to any currently defined element. In this case, the element's definition is put on hold as if it hasn't loaded, until the element mentioned in the <code>extends</code> attribute is loaded.</li>
    <li>The value of the <code>is</code> attribute does not begin with an <code>x-</code>. This is resolved by dropping the <code>is</code> attribute altogether.</li>
    <li>The value of the <code>name</code> attribute does not begin with an <code>x-</code>. The definition is considered invalid and is ignored.</li>
</ul>

<h2 id="shadow-dom-section"><span class="section">6</span> Shadow DOM</h2>

<p>Shadow DOM is a tree of DOM nodes. Shadow DOM can be applied to a custom element declaratively, by including a template, or to any element imperatively using JavaScript.</p>

<object data="shadow-dom-subtrees.svg" width="800" height="430"></object>

<p>When an element has shadow DOM, the element's children are not rendered; the content of the shadow DOM is rendered instead.</p>

<object data="shadow-rendering.svg" width="450" height="400"></object>

<h3 id="content-and-shadow-elements"><span class="section">6.1</span> Content and Shadow Elements</h3>

<p>Any <a href="http://www.w3.org/TR/shadow-dom/#dfn-shadow-dom-subtree">shadow DOM subtree</a> can specify <a href="http://www.w3.org/TR/shadow-dom/#dfn-insertion-point">insertion points</a> for element's children by using a <code><a href="http://www.w3.org/TR/shadow-dom/#content-element">&lt;content&gt;</a></code> element:</p>

<pre class="prettyprint"><code><span class="pln">
</span><span class="tag">&lt;div&gt;</span><span class="pln">
    </span><span class="tag">&lt;div</span><span class="pln"> </span><span class="atn">class</span><span class="pun">=</span><span class="atv">"stuff"</span><span class="tag">&gt;</span><span class="pln">
        </span><span class="tag">&lt;content&gt;</span><span class="com">&lt;!-- all children will appear here --&gt;</span><span class="tag">&lt;/content&gt;</span><span class="pln">
    </span><span class="tag">&lt;/div&gt;</span><span class="pln">
</span><span class="tag">&lt;/div&gt;</span></code></pre>

<p>The <code><a href="http://www.w3.org/TR/shadow-dom/#content-element">&lt;content&gt;</a></code> element acts as an <a href="http://www.w3.org/TR/shadow-dom/#dfn-insertion-point">insertion point</a> for rendering only—it does not change where the elements appear in DOM. When rendering, the element's children just appear in place of the <code><a href="http://www.w3.org/TR/shadow-dom/#content-element">&lt;content&gt;</a></code> element. And yes, you can have more than one <code><a href="http://www.w3.org/TR/shadow-dom/#content-element">&lt;content&gt;</a></code> in the <a href="http://www.w3.org/TR/shadow-dom/#dfn-shadow-dom-subtree">shadow DOM subtree</a>! The <code><a href="http://www.w3.org/TR/shadow-dom/#markup-content-select">select</a></code> attribute gives you a handy way to choose which children appear at which <a href="http://www.w3.org/TR/shadow-dom/#dfn-insertion-point">insertion point</a>. If there is more than one <code><a href="http://www.w3.org/TR/shadow-dom/#content-element">&lt;content&gt;</a></code> element, the tree order dictates when each of these elements takes a pass at selecting the children. Once the child is selected to be rendered at one <a href="http://www.w3.org/TR/shadow-dom/#dfn-insertion-point">insertion point</a>, it can't be claimed by another one.</p>

<pre class="prettyprint"><code><span class="pln">
</span><span class="tag">&lt;div&gt;</span><span class="pln">
    </span><span class="tag">&lt;content</span><span class="pln"> </span><span class="atn">select</span><span class="pun">=</span><span class="atv">"h1.cool"</span><span class="tag">&gt;</span><span class="com">&lt;!-- all h1.cool children will
        appear here --&gt;</span><span class="tag">&lt;/content&gt;</span><span class="pln">
    </span><span class="tag">&lt;div</span><span class="pln"> </span><span class="atn">class</span><span class="pun">=</span><span class="atv">"cool"</span><span class="tag">&gt;</span><span class="pln">
        </span><span class="tag">&lt;content</span><span class="pln"> </span><span class="atn">select</span><span class="pun">=</span><span class="atv">".cool"</span><span class="tag">&gt;</span><span class="com">&lt;!-- all .cool children
            (except the ones that are h1.cool) appear here --&gt;</span><span class="tag">&lt;/content&gt;</span><span class="pln">
    </span><span class="tag">&lt;/div&gt;</span><span class="pln">
    </span><span class="tag">&lt;div</span><span class="pln"> </span><span class="atn">class</span><span class="pun">=</span><span class="atv">"stuff"</span><span class="tag">&gt;</span><span class="pln">
        </span><span class="tag">&lt;content&gt;</span><span class="com">&lt;!-- all remaining children will
            appear here --&gt;</span><span class="tag">&lt;/content&gt;</span><span class="pln">
    </span><span class="tag">&lt;/div&gt;</span><span class="pln">
</span><span class="tag">&lt;/div&gt;</span></code></pre>

<h3 id="multiple-shadow-subtrees"><span class="section">6.2</span> Multiple Shadow Subtrees</h3>

<p>Any element can have more than one <a href="http://www.w3.org/TR/shadow-dom/#dfn-shadow-dom-subtree">shadow DOM subtree</a>. Don't look so puzzled! Suppose you are extending a DOM element that already has a <a href="http://www.w3.org/TR/shadow-dom/#dfn-shadow-dom-subtree">shadow DOM subtree</a>. What happens to that poor old tree? We could just ditch it for the new arboreal hotness, but what if you don't want to? What if you want reuse it?</p>

<p>For this noble purpose, we have a special <code><a href="http://www.w3.org/TR/shadow-dom/#shadow-element">&lt;shadow&gt;</a></code> element, which acts as an <a href="http://www.w3.org/TR/shadow-dom/#dfn-insertion-point">insertion point</a> for the, you guessed it, the previously applied <a href="http://www.w3.org/TR/shadow-dom/#dfn-shadow-dom-subtree">shadow DOM subtree</a> of this element (also known as the <a href="http://www.w3.org/TR/shadow-dom/#dfn-older-tree">older tree</a>). For instance, you can take existing range slider (that's <code>&lt;input type="range"&gt;</code>) and extend it, adding your extra shadow schmutz to it:</p>

<pre class="prettyprint"><code><span class="pln">
</span><span class="tag">&lt;div&gt;</span><span class="pln">
    </span><span class="tag">&lt;shadow&gt;</span><span class="com">&lt;!-- range slider renders here --&gt;</span><span class="tag">&lt;/shadow&gt;</span><span class="pln">
    </span><span class="tag">&lt;div</span><span class="pln"> </span><span class="atn">class</span><span class="pun">=</span><span class="atv">"ticks"</span><span class="tag">&gt;</span><span class="pln"> … </span><span class="tag">&lt;/div&gt;</span><span class="pln">
</span><span class="tag">&lt;/div&gt;</span></code></pre>

<p>Since an element can have multiple shadows, we need to understand how these shadows interact with each other and what effect these interactions have on rendering of the element's children.</p>

<p>First, the order in which the <a href="http://www.w3.org/TR/shadow-dom/#dfn-shadow-dom-subtree">shadow DOM subtrees</a> are applied is important. Because you cannot remove a shadow DOM, the order is typically like this:</p>
<ol>
    <li>element shadow DOM (I got here first, nyah!)</li>
    <li>shadow DOM of the element sub-class</li>
    <li>shadow DOM of the element sub-sub-class</li>
    <li>…</li>
    <li>some shadow DOM added using script</li>
    <li>decorator shadow (applied and removed with CSS rules—not technically a shadow DOM, but can, too, have <code><a href="http://www.w3.org/TR/shadow-dom/#content-element">&lt;content&gt;</a></code> and <code><a href="http://www.w3.org/TR/shadow-dom/#shadow-element">&lt;shadow&gt;</a></code> elements)</li>
</ol>

<p>Next, we take this <a href="http://www.w3.org/TR/shadow-dom/#dfn-tree-stack">stack</a> of <a href="http://www.w3.org/TR/shadow-dom/#dfn-shadow-dom-subtree">shadow DOM subtrees</a> and traverse it backwards, starting with the last-applied (or <a href="http://www.w3.org/TR/shadow-dom/#dfn-youngest-tree">youngest</a>) subtree. Each <code><a href="http://www.w3.org/TR/shadow-dom/#content-element">&lt;content&gt;</a></code> instance, encountered in tree order, grabs the element's children that it needs as usual.</p>

<p>This is where things get interesting. Once we're done shuffling the children into their right places to render, we check and see if we have a <code><a href="http://www.w3.org/TR/shadow-dom/#shadow-element">&lt;shadow&gt;</a></code> element. If we don't, we're done.</p>

<p>If we do, we plop the next shadow subtree in our list in place of the <code><a href="http://www.w3.org/TR/shadow-dom/#shadow-element">&lt;shadow&gt;</a></code> element, and rinse-repeat first replacing <code><a href="http://www.w3.org/TR/shadow-dom/#content-element">&lt;content&gt;</a></code> <a href="http://www.w3.org/TR/shadow-dom/#dfn-insertion-point">insertion points</a>, then <code><a href="http://www.w3.org/TR/shadow-dom/#shadow-element">&lt;shadow&gt;</a></code> until we reach the start of the list.</p>

<p>And then—ta-da!—we have our wondrous shadow DOM Yggdrasil, ready for rendering.</p>

<object data="shadow-stack.svg" width="500" height="600"></object>

<p>Here's an easy way to remember how this works:</p>
<ul>
    <li>The most recently applied <a href="http://www.w3.org/TR/shadow-dom/#dfn-shadow-dom-subtree">shadow DOM subtree</a> has the best shot of getting fresh children for its <code><a href="http://www.w3.org/TR/shadow-dom/#content-element">&lt;content&gt;</a></code> <a href="http://www.w3.org/TR/shadow-dom/#dfn-insertion-point">insertion points</a> (unfair, I know!)</li>
    <li>Once it's had its way, the next most recent <a href="http://www.w3.org/TR/shadow-dom/#dfn-shadow-dom-subtree">shadow DOM subtree</a>—if even allowed to—can rummage through the remaining children.</li>
    <li>Cycle repeats until either the current <a href="http://www.w3.org/TR/shadow-dom/#dfn-shadow-dom-subtree">shadow DOM subtree</a> has no <code><a href="http://www.w3.org/TR/shadow-dom/#shadow-element">&lt;shadow&gt;</a></code> element, or we've processed the oldest DOM subtree for this element.</li>
</ul>

<h3 id="css-and-shadow-dom"><span class="section">6.3</span> CSS and Shadow DOM</h3>

<p>When building a custom element, you often want to prevent document styles from interfering with what you've painstakingly crafted.</p>

<p>Lucky for you, the <a href="http://www.w3.org/TR/shadow-dom/#dfn-shadow-dom-subtree">shadow DOM subtree</a> is surrounded by an invisible <a href="http://www.w3.org/TR/shadow-dom/#dfn-shadow-boundary">boundary</a>, only letting the user agent styles apply by default. The inheritance still works as usual—more on that later.</p>

<p>You can relax this <a href="http://www.w3.org/TR/shadow-dom/#dfn-shadow-boundary">boundary</a> with the <code>apply-author-styles</code> attribute on the <code>&lt;template&gt;</code> element. With the attribute present, document's author styles start applying in the <a href="http://www.w3.org/TR/shadow-dom/#dfn-shadow-dom-subtree">shadow DOM subtree</a>.</p>

<p>Conversely, you can make the <a href="http://www.w3.org/TR/shadow-dom/#dfn-shadow-boundary">boundary</a> even stronger by setting the <code>reset-style-inherifance</code> attribute on the <code>&lt;template&gt;</code> element. With the attribute present, <em>all</em> styles are reset to <a href="http://www.w3.org/TR/CSS21/about.html#initial-value">initial</a> values at the <a href="http://www.w3.org/TR/shadow-dom/#dfn-shadow-boundary">shadow boundary</a>. No more need for lengthy reset stylesheets! Just set the attribute and start with a clean slate.</p>

<p>There is a similar <a href="http://www.w3.org/TR/shadow-dom/#dfn-shadow-boundary">boundary</a> between the <code><a href="http://www.w3.org/TR/shadow-dom/#content-element">&lt;content&gt;</a></code> element and element's children, rendered in its place. The styles from the <a href="http://www.w3.org/TR/shadow-dom/#dfn-shadow-dom-subtree">shadow DOM subtree</a> do not apply to the element's children.</p>


<!-- <p>And you can control that too, using <code>apply-shadow-styles</code> attribute on the <code>&lt;content&gt;</code> element. -->

<p>The magic <a href="http://www.w3.org/TR/shadow-dom/#dfn-shadow-boundary">boundary</a> also prevents selectors from reaching into the <a href="http://www.w3.org/TR/shadow-dom/#dfn-shadow-dom-subtree">shadow DOM subtree</a>, skipping it altogether. For example, if <code>&lt;div id="foo"&gt;</code> had this <a href="http://www.w3.org/TR/shadow-dom/#dfn-shadow-dom-subtree">shadow DOM subtree</a>:</p>

<pre class="prettyprint"><code><span class="pln">
</span><span class="tag">&lt;a</span><span class="pln"> </span><span class="atn">href</span><span class="pun">=</span><span class="atv">"http://example.com"</span><span class="tag">&gt;</span><span class="pln">shadow link</span><span class="tag">&lt;/a&gt;</span><span class="pln">
</span><span class="tag">&lt;content&gt;&lt;/content&gt;</span></code></pre>

<p>and a child</p>

<pre class="prettyprint"><code><span class="pln">
</span><span class="tag">&lt;a</span><span class="pln"> </span><span class="atn">href</span><span class="pun">=</span><span class="atv">"http://example.org"</span><span class="tag">&gt;</span><span class="pln">light link</span><span class="tag">&lt;/a&gt;</span></code></pre>

<p>both <code>div#foo&gt;a</code> and <code>div#foo a</code> will select the child (light link), not the anchor in the shadow DOM (shadow link).</p>

<p>If the component authors wish to allow some styling of the <a href="http://www.w3.org/TR/shadow-dom/#dfn-shadow-dom-subtree">shadow DOM subtree</a> by the component users, they can do so with <a href="http://www.w3.org/TR/shadow-dom/#css-variables">CSS variables</a>. The variable definitions specified on the shadow DOM host element are also resolved inside of the <a href="http://www.w3.org/TR/shadow-dom/#dfn-shadow-dom-subtree">shadow DOM subtree</a>.</p>

<h3 id="events"><span class="section">6.4</span> Events in Shadow DOM</h3>

<p>To ensure that the elements of the <a href="http://www.w3.org/TR/shadow-dom/#dfn-shadow-dom-subtree">shadow DOM subtree</a> are not exposed outside of the subtree, there's a fair bit of work that happens while dispatching an event from inside of the subtree.</p>

<p>First, some events (like mutation and selectstart events) are just plain <a href="http://www.w3.org/TR/shadow-dom/#events-that-are-always-stopped">prevented</a> from escaping out of the <a href="http://www.w3.org/TR/shadow-dom/#dfn-shadow-dom-subtree">shadow DOM subtree</a>—they are never heard from the outside.</p>

<p>Those events that do cross the shadow DOM <a href="http://www.w3.org/TR/shadow-dom/#dfn-shadow-boundary">boundary</a> are <a href="http://www.w3.org/TR/shadow-dom/#event-retargeting">retargeted</a>—their <code>target</code> and <code>relatedTarget</code> values are modified to point to the element that <a href="http://www.w3.org/TR/shadow-dom/#dfn-shadow-host">hosts</a> the <a href="http://www.w3.org/TR/shadow-dom/#dfn-shadow-dom-subtree">shadow DOM subtree</a>.</p>

<p>In some cases, like <code>DOMFocusIn</code>, <code>mouseover</code>, <code>mouseout</code> events have to be given extra attention: if you're moving a mouse between two elements inside of the shadow subtree, you don't want to be spamming the document with these events, since they will appear as non-sensical babbling after the retargeting (what? the element just reported that the mouse just moved from itself back to itself?!)</p>

<h3 id="making-more-shadows"><span class="section">6.5</span> Making More Shadows</h3>

<p>As implied before, you can always add a <a href="http://www.w3.org/TR/shadow-dom/#dfn-shadow-dom-subtree">shadow DOM subtree</a> to any DOM element in one line of code:</p>

<pre class="prettyprint"><code><span class="pln">
</span><span class="kwd">var</span><span class="pln"> shadow </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">new</span><span class="pln"> </span><span class="typ">ShadowRoot</span><span class="pun">(</span><span class="pln">anyElement</span><span class="pun">);</span></code></pre>

<p>This does two things:</p>
<ol>
    <li>Creates a brand-spanking-new <a href="http://www.w3.org/TR/shadow-dom/#shadow-root-object">ShadowRoot</a> instance, which you should imagine as this shadowy, invisible other side of your element. It's like a tiny document that lives inside of our custom element, and serves as the root of your <a href="http://www.w3.org/TR/shadow-dom/#dfn-shadow-dom-subtree">shadow DOM subtree</a>.</li>
    <li>Sets <code>anyElement</code> as the <a href="http://www.w3.org/TR/shadow-dom/#dfn-shadow-host">host</a> of this newly created <a href="http://www.w3.org/TR/shadow-dom/#dfn-shadow-dom-subtree">shadow DOM subtree</a>.</li>
</ol>

<p>The important thing to remember is that while you can add new <a href="http://www.w3.org/TR/shadow-dom/#dfn-shadow-dom-subtree">shadow DOM subtrees</a> this way, you can never remove them: they just keep stacking up.</p>

<h2 id="decorators-vs-custom-elements"><span class="section">7</span> Decorators vs. Custom Elements</h2>

<p>Decorator shadows are never accessible with DOM. When the decorator is created, the <a href="http://www.w3.org/TR/shadow-dom/#dfn-shadow-dom-subtree">shadow DOM subtree</a> is placed in a cold, dark place—for storage. Once the decorator is applied to an element, this <a href="http://www.w3.org/TR/shadow-dom/#dfn-shadow-dom-subtree">shadow DOM subtree</a> is used to produce the rendering, but its nodes are never accessible from script. You can, however listen to events that happen inside the decorator shadow using EventController.</p>

<p>An easy way to think of the decorator shadow is a projection. You can see it, but never can actually touch it.</p>

<p>On the other hand, the custom element shadow (or any <a href="http://www.w3.org/TR/shadow-dom/#dfn-shadow-dom-subtree">shadow DOM subtree</a> created using script) is a real DOM tree that you as the custom element author can change as you please.</p>

<p>Another important difference between the two is the fact that you can <em>unapply</em> a decorator. On the other hand, once you've instantiated a custom element, its qualities—including its <a href="http://www.w3.org/TR/shadow-dom/#dfn-shadow-dom-subtree">shadow DOM subtree</a>—are inherent part of element's identity.</p>

<h2 id="external-custom-elements-and-decorators"><span class="section">8</span> External Custom Elements and Decorators</h2>

<p>Custom elements and decorators can be loaded from external files using the link tag:

</p><pre class="prettyprint"><code><span class="pln">
</span><span class="tag">&lt;link</span><span class="pln"> </span><span class="atn">rel</span><span class="pun">=</span><span class="atv">"components"</span><span class="pln"> </span><span class="atn">href</span><span class="pun">=</span><span class="atv">"goodies.html"</span><span class="tag">&gt;</span></code></pre>

<p>Only <code>decorator</code> elements, <code>element</code> elements and <code>script</code> elements are interpreted by the UA. The DOM of this document is not available to script. The origin of the embedding document is used as the origin of the embedded document. Script runs as though it was async defer. The custom element definitions and decorators are not made available until the scripts have run. Documents which are retrieved cross-origin use CORs to determine that the definitions are designed to run cross-site.</p>

<h2 id="isolation-confinement-and-encapsulation"><span class="section">9</span> Isolation, Confinement and Encapsulation</h2>

<p><dfn id="component-isolation-definition">Component isolation</dfn> can be viewed as combination of two parts:</p>
<ul>
    <li><dfn id="confinement-definition">confinement</dfn>, when the document wants to prevent a component from accessing document information, and</li>
    <li><dfn id="encapsulation-definition">encapsulation</dfn>, when the component wants to prevent the document from accessing inner state of the component.</li>
</ul>

<p>Component encapsulation is partially enforced with shadow DOM, ensuring that shadow DOM nodes never appear in the event dispatch, range, focus-related DOM accessors or any APIs that query DOM nodes. It is up the author of the component to choose whether the inner state is exposed.</p>

<p>Component confinement is trickier, but possible using existing primitives, such as <code>iframe</code> or workers. The general solution would be to treat the component as the corruptible agent, which is responsible for the component user interface and interaction with the document. The component would then load a worker (or an <code>iframe</code>) and communicate with it using <code>postMessage</code>:</p>

<pre class="prettyprint"><code><span class="pln">
</span><span class="com">&lt;!--- located at http://example.com/adorable/button --&gt;</span><span class="pln">
</span><span class="tag">&lt;element</span><span class="pln"> </span><span class="atn">name</span><span class="pun">=</span><span class="atv">"x-adore-button"</span><span class="pln"> </span><span class="atn">extends</span><span class="pun">=</span><span class="atv">"button"</span><span class="tag">&gt;</span><span class="pln">
    </span><span class="tag">&lt;script&gt;</span><span class="pln">
        </span><span class="kwd">var</span><span class="pln"> service </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">new</span><span class="pln"> </span><span class="typ">Worker</span><span class="pun">(</span><span class="str">"http://example.com/adorable/service/worker.js"</span><span class="pun">);</span><span class="pln">
        service</span><span class="pun">.</span><span class="pln">onmessage </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">function</span><span class="pun">(</span><span class="pln">event</span><span class="pun">)</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
            </span><span class="com">// process responses from the service.</span><span class="pln">
            </span><span class="pun">…</span><span class="pln">
        </span><span class="pun">}</span><span class="pln">
        </span><span class="com">// set up UI.</span><span class="pln">
        </span><span class="pun">…</span><span class="pln">
        </span><span class="com">// start interacting with the worker.</span><span class="pln">
        service</span><span class="pun">.</span><span class="pln">postMessage</span><span class="pun">(</span><span class="str">"hello"</span><span class="pun">);</span><span class="pln">
    </span><span class="tag">&lt;/script&gt;</span><span class="pln">
    </span><span class="tag">&lt;template&gt;</span><span class="pln">I adore this</span><span class="tag">&lt;/template&gt;</span><span class="pln">
</span><span class="tag">&lt;/element&gt;</span></code></pre>

<h2 id="example"><span class="section">10</span> Example</h2>

<p>Suppose we we want to display a clickable map of timezones instead of a select element. Here's how one could implement this using decorators:</p>

<pre class="prettyprint"><code><span class="pln">
</span><span class="tag">&lt;decorator</span><span class="pln"> </span><span class="atn">id</span><span class="pun">=</span><span class="atv">"timezone-map"</span><span class="tag">&gt;</span><span class="pln">
    </span><span class="tag">&lt;script&gt;</span><span class="pln">
        </span><span class="kwd">var</span><span class="pln"> timezones </span><span class="pun">=</span><span class="pln"> </span><span class="pun">[</span><span class="str">"PST"</span><span class="pun">,</span><span class="pln"> </span><span class="pun">…</span><span class="pln"> </span><span class="pun">];</span><span class="pln">

        </span><span class="kwd">function</span><span class="pln"> createHandler</span><span class="pun">(</span><span class="pln">timezone</span><span class="pun">)</span><span class="pln">
        </span><span class="pun">{</span><span class="pln">
            </span><span class="kwd">this</span><span class="pun">.</span><span class="pln">listen</span><span class="pun">({</span><span class="pln">
                selector</span><span class="pun">:</span><span class="pln"> </span><span class="str">"#"</span><span class="pln"> </span><span class="pun">+</span><span class="pln"> timezone</span><span class="pun">,</span><span class="pln">
                type</span><span class="pun">:</span><span class="pln"> </span><span class="str">"click"</span><span class="pun">,</span><span class="pln">
                handler</span><span class="pun">:</span><span class="pln"> </span><span class="kwd">function</span><span class="pun">()</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
                    </span><span class="com">// Decorators are late-bound, we must check for type.</span><span class="pln">
                    </span><span class="kwd">if</span><span class="pln"> </span><span class="pun">(</span><span class="kwd">this</span><span class="pln"> instanceof </span><span class="typ">HTMLSelectElement</span><span class="pun">)</span><span class="pln">
                        </span><span class="kwd">this</span><span class="pun">.</span><span class="pln">selectedIndex </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">this</span><span class="pun">[</span><span class="pln">timezone</span><span class="pun">].</span><span class="pln">index</span><span class="pun">;</span><span class="pln">
                </span><span class="pun">}</span><span class="pln">
            </span><span class="pun">});</span><span class="pln">
        </span><span class="pun">}</span><span class="pln">

        timezones</span><span class="pun">.</span><span class="pln">forEach</span><span class="pun">(</span><span class="pln">createHandler</span><span class="pun">,</span><span class="pln"> </span><span class="kwd">this</span><span class="pun">);</span><span class="pln">
    </span><span class="tag">&lt;/script&gt;</span><span class="pln">
    </span><span class="tag">&lt;template&gt;</span><span class="pln">
        </span><span class="tag">&lt;svg</span><span class="pln"> …</span><span class="tag">&gt;</span><span class="pln">
            </span><span class="tag">&lt;g</span><span class="pln"> </span><span class="atn">id</span><span class="pun">=</span><span class="atv">"worldShapes"</span><span class="tag">&gt;</span><span class="pln"> … </span><span class="tag">&lt;/g&gt;</span><span class="pln">
            </span><span class="tag">&lt;g</span><span class="pln"> </span><span class="atn">id</span><span class="pun">=</span><span class="atv">"timezoneShapes"</span><span class="tag">&gt;</span><span class="pln">
                </span><span class="tag">&lt;path</span><span class="pln"> </span><span class="atn">id</span><span class="pun">=</span><span class="atv">"PST"</span><span class="pln"> …</span><span class="tag">&gt;</span><span class="pln">
                </span><span class="tag">&lt;path</span><span class="pln"> </span><span class="atn">id</span><span class="pun">=</span><span class="atv">"CST"</span><span class="pln"> …</span><span class="tag">&gt;</span><span class="pln">
            </span><span class="tag">&lt;/g&gt;</span><span class="pln">
            …
        </span><span class="tag">&lt;/svg&gt;</span><span class="pln">
    </span><span class="tag">&lt;/template&gt;</span><span class="pln">
</span><span class="tag">&lt;/decorator&gt;</span></code></pre>

<p>You would apply this decorator as:</p>

<pre class="prettyprint"><code><span class="pln">
</span><span class="kwd">select</span><span class="pun">.</span><span class="pln">timezones </span><span class="pun">{</span><span class="pln">
    decorator</span><span class="pun">:</span><span class="pln"> url</span><span class="pun">(</span><span class="com">#timezone-map);</span><span class="pln">
</span><span class="pun">}</span></code></pre>

<p>provided that there's the following markup in the document:</p>

<pre class="prettyprint"><code><span class="pln">
</span><span class="tag">&lt;select</span><span class="pln"> </span><span class="atn">class</span><span class="pun">=</span><span class="atv">"timezones"</span><span class="tag">&gt;</span><span class="pln">
    </span><span class="tag">&lt;option&gt;</span><span class="pln">PST</span><span class="tag">&lt;/option&gt;</span><span class="pln">
    …
</span><span class="tag">&lt;/select&gt;</span></code></pre>

<p>And here's the implementation using custom elements:</p>

<pre class="prettyprint"><code><span class="pln">
</span><span class="tag">&lt;element</span><span class="pln"> </span><span class="atn">extends</span><span class="pun">=</span><span class="atv">"select"</span><span class="pln"> </span><span class="atn">name</span><span class="pun">=</span><span class="atv">"x-timezone-map"</span><span class="pln"> </span><span class="atn">constructor</span><span class="pun">=</span><span class="atv">"MapSelector"</span><span class="tag">&gt;</span><span class="pln">
    </span><span class="tag">&lt;script&gt;</span><span class="pln">
        </span><span class="kwd">this</span><span class="pun">.</span><span class="pln">lifecycle</span><span class="pun">({</span><span class="pln">
            created</span><span class="pun">:</span><span class="pln"> </span><span class="kwd">function</span><span class="pun">(</span><span class="pln">shadowRoot</span><span class="pun">)</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
                </span><span class="kwd">var</span><span class="pln"> select </span><span class="pun">=</span><span class="pln"> shadowRoot</span><span class="pun">.</span><span class="pln">shadowHost</span><span class="pun">;</span><span class="pln">
                </span><span class="kwd">var</span><span class="pln"> timezones </span><span class="pun">=</span><span class="pln"> shadowRoot</span><span class="pun">.</span><span class="pln">querySelector</span><span class="pun">(</span><span class="str">"#timezoneShapes"</span><span class="pun">);</span><span class="pln">
                timezones</span><span class="pun">.</span><span class="pln">addEventListener</span><span class="pun">(</span><span class="str">"click"</span><span class="pun">,</span><span class="pln"> </span><span class="kwd">function</span><span class="pun">(</span><span class="pln">event</span><span class="pun">)</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
                    </span><span class="kwd">if</span><span class="pln"> </span><span class="pun">(</span><span class="pln">event</span><span class="pun">.</span><span class="pln">target </span><span class="pun">!=</span><span class="pln"> </span><span class="kwd">this</span><span class="pun">)</span><span class="pln">
                        select</span><span class="pun">.</span><span class="pln">selectedIndex </span><span class="pun">=</span><span class="pln"> select</span><span class="pun">[</span><span class="pln">event</span><span class="pun">.</span><span class="pln">target</span><span class="pun">.</span><span class="pln">id</span><span class="pun">].</span><span class="pln">index</span><span class="pun">;</span><span class="pln">
                </span><span class="pun">});</span><span class="pln">
            </span><span class="pun">}</span><span class="pln">
        </span><span class="pun">});</span><span class="pln">

        </span><span class="typ">MapSelector</span><span class="pun">.</span><span class="pln">prototype</span><span class="pun">.</span><span class="pln">isDaylightSaving </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">function</span><span class="pun">()</span><span class="pln"> </span><span class="pun">{</span><span class="pln"> </span><span class="com">/* … */</span><span class="pln"> </span><span class="pun">}</span><span class="pln">
    </span><span class="tag">&lt;/script&gt;</span><span class="pln">
    </span><span class="tag">&lt;template&gt;</span><span class="pln">
        </span><span class="tag">&lt;svg&gt;</span><span class="pln">
            </span><span class="tag">&lt;g</span><span class="pln"> </span><span class="atn">id</span><span class="pun">=</span><span class="atv">"worldShapes"</span><span class="tag">&gt;</span><span class="pln"> … </span><span class="tag">&lt;/g&gt;</span><span class="pln">
            </span><span class="tag">&lt;g</span><span class="pln"> </span><span class="atn">id</span><span class="pun">=</span><span class="atv">"timezoneShapes"</span><span class="tag">&gt;</span><span class="pln">
                </span><span class="tag">&lt;path</span><span class="pln"> </span><span class="atn">id</span><span class="pun">=</span><span class="atv">"PST"</span><span class="pln"> …</span><span class="tag">&gt;</span><span class="pln">
                </span><span class="tag">&lt;path</span><span class="pln"> </span><span class="atn">id</span><span class="pun">=</span><span class="atv">"CST"</span><span class="pln"> …</span><span class="tag">&gt;</span><span class="pln">
            </span><span class="tag">&lt;/g&gt;</span><span class="pln">
            …
        </span><span class="tag">&lt;/svg&gt;</span><span class="pln">
    </span><span class="tag">&lt;/template&gt;</span><span class="pln">
</span><span class="tag">&lt;/element&gt;</span></code></pre>

<p>You would use this custom element like so:</p>

<pre class="prettyprint"><code><span class="pln">
</span><span class="tag">&lt;select</span><span class="pln"> </span><span class="atn">is</span><span class="pun">=</span><span class="atv">"x-timezone-map"</span><span class="tag">&gt;</span><span class="pln">
    </span><span class="tag">&lt;option&gt;</span><span class="pln">PST</span><span class="tag">&lt;/option&gt;</span><span class="pln">
    …
</span><span class="tag">&lt;/select&gt;</span></code></pre>

<p>For more examples, take a look at the <a href="http://dvcs.w3.org/hg/webcomponents/raw-file/tip/samples/index.html">Web Components Samples</a>.</p>

<h2 id="appendix-a-interfaces">Appendix A. Interfaces</h2>

<pre class="prettyprint"><code><span class="pln">
</span><span class="kwd">partial</span><span class="pln"> </span><span class="kwd">interface</span><span class="pln"> </span><span class="typ">HTMLElement</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
    </span><span class="kwd">readonly</span><span class="pln"> attribute </span><span class="typ">DOMString</span><span class="pln"> </span><span class="kwd">is</span><span class="pun">;</span><span class="pln">
</span><span class="pun">}</span><span class="pln">

</span><span class="kwd">interface</span><span class="pln"> </span><span class="typ">HTMLTemplateElement</span><span class="pln"> </span><span class="pun">:</span><span class="pln"> </span><span class="typ">HTMLElement</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
    </span><span class="kwd">readonly</span><span class="pln"> attribute </span><span class="typ">DocumentFragment</span><span class="pln"> content</span><span class="pun">;</span><span class="pln">
</span><span class="pun">}</span><span class="pln">

</span><span class="kwd">interface</span><span class="pln"> </span><span class="typ">HTMLDecoratorElement</span><span class="pln"> </span><span class="pun">:</span><span class="pln"> </span><span class="typ">HTMLElement</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
    attribute </span><span class="kwd">bool</span><span class="pln"> applyAuthorStyles</span><span class="pun">;</span><span class="pln">
    </span><span class="kwd">void</span><span class="pln"> listen</span><span class="pun">(</span><span class="typ">ListenInit</span><span class="pln"> listenInitDict</span><span class="pun">);</span><span class="pln">
</span><span class="pun">}</span><span class="pln">
dictionary </span><span class="typ">ListenInit</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
    </span><span class="typ">DOMString</span><span class="pln"> type</span><span class="pun">;</span><span class="pln">
    </span><span class="typ">DOMString</span><span class="pln"> selector</span><span class="pun">;</span><span class="pln">
    </span><span class="typ">EventHandler</span><span class="pln"> handler</span><span class="pun">;</span><span class="pln">
</span><span class="pun">}</span><span class="pln">

</span><span class="kwd">interface</span><span class="pln"> </span><a href="http://www.w3.org/TR/shadow-dom/#api-html-content-element"><span class="typ">HTMLContentElement</span></a><span class="pln"> </span><span class="pun">:</span><span class="pln"> </span><a href="http://dev.w3.org/html5/spec/Overview.html#htmlelement"><span class="typ">HTMLElement</span></a><span class="pln"> </span><span class="pun">{</span><span class="pln">
    attribute </span><span class="typ">DOMString</span><span class="pln"> </span><a href="http://www.w3.org/TR/shadow-dom/#api-html-content-element-select"><span class="kwd">select</span></a><span class="pun">;</span><span class="pln">
</span><span class="pun">}</span><span class="pln">

</span><span class="kwd">interface</span><span class="pln"> </span><span class="typ">HTMLElementElement</span><span class="pln"> </span><span class="pun">:</span><span class="pln"> </span><span class="typ">HTMLElement</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
    attribute </span><span class="typ">DOMString</span><span class="pln"> </span><span class="kwd">extends</span><span class="pun">;</span><span class="pln">
    attribute </span><span class="typ">DOMString</span><span class="pln"> name</span><span class="pun">;</span><span class="pln">
    attribute </span><span class="kwd">bool</span><span class="pln"> applyAuthorStyles</span><span class="pun">;</span><span class="pln">
    </span><span class="kwd">readonly</span><span class="pln"> attribute </span><span class="typ">Function</span><span class="pln"> generatedConstructor</span><span class="pun">;</span><span class="pln">
    </span><span class="kwd">void</span><span class="pln"> lifecycle</span><span class="pun">(</span><span class="typ">LifecycleInit</span><span class="pln"> lifecycleInitDict</span><span class="pun">);</span><span class="pln">
    </span><span class="kwd">void</span><span class="pln"> reflectAttribute</span><span class="pun">(</span><span class="typ">DOMString</span><span class="pln"> attributeName</span><span class="pun">,</span><span class="pln">
    </span><span class="typ">DOMString</span><span class="pln"> propertyName</span><span class="pun">,</span><span class="pln"> </span><span class="typ">ChangeCallback</span><span class="pln"> changeCallback</span><span class="pun">);</span><span class="pln">
    </span><span class="kwd">void</span><span class="pln"> setupEvent</span><span class="pun">(</span><span class="typ">DOMString</span><span class="pln"> eventName</span><span class="pun">);</span><span class="pln">
</span><span class="pun">}</span><span class="pln">
dictionary </span><span class="typ">LifecycleInit</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
    </span><span class="typ">Function</span><span class="pln"> attributeChanged</span><span class="pun">(</span><span class="pln">
            </span><span class="typ">DOMString</span><span class="pln"> name</span><span class="pun">,</span><span class="pln">
            </span><span class="typ">DOMString</span><span class="pln"> newValue</span><span class="pun">,</span><span class="pln">
            </span><span class="typ">DOMString</span><span class="pln"> oldValue</span><span class="pun">);</span><span class="pln">
    </span><span class="typ">Function</span><span class="pln"> created</span><span class="pun">(</span><span class="typ">ShadowRoot</span><span class="pln"> shadowRoot</span><span class="pun">);</span><span class="pln">
    </span><span class="typ">Function</span><span class="pln"> inserted</span><span class="pun">();</span><span class="pln">
    </span><span class="typ">Function</span><span class="pln"> removed</span><span class="pun">();</span><span class="pln">
</span><span class="pun">}</span><span class="pln">
</span><span class="pun">[</span><span class="typ">Callback</span><span class="pun">=</span><span class="typ">FunctionOnly</span><span class="pun">,</span><span class="pln"> </span><span class="typ">NoInterfaceObject</span><span class="pun">]</span><span class="pln">
</span><span class="kwd">interface</span><span class="pln"> </span><span class="typ">ChangeCallback</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
    </span><span class="kwd">void</span><span class="pln"> handleEvent</span><span class="pun">(</span><span class="typ">DOMString</span><span class="pln"> name</span><span class="pun">,</span><span class="pln"> </span><span class="typ">DOMString</span><span class="pln"> newValue</span><span class="pun">,</span><span class="pln"> </span><span class="typ">DOMString</span><span class="pln"> oldValue</span><span class="pun">);</span><span class="pln">
</span><span class="pun">}</span><span class="pln">

</span><span class="kwd">interface</span><span class="pln"> </span><a href="http://www.w3.org/TR/shadow-dom/#api-html-shadow-element"><span class="typ">HTMLShadowElement</span></a><span class="pln"> </span><span class="pun">:</span><span class="pln"> </span><a href="http://dev.w3.org/html5/spec/Overview.html#htmlelement"><span class="typ">HTMLElement</span></a><span class="pln"> </span><span class="pun">{</span><span class="pln">
</span><span class="pun">}</span><span class="pln">

</span><span class="pun">[</span><span class="typ">Constructor</span><span class="pun">(</span><span class="kwd">in</span><span class="pln"> </span><span class="typ">HTMLElement</span><span class="pln"> element</span><span class="pun">)</span><span class="pln"> raises </span><span class="pun">(</span><span class="typ">DOMException</span><span class="pun">)]</span><span class="pln">
</span><span class="kwd">interface</span><span class="pln"> </span><a href="http://www.w3.org/TR/shadow-dom/#api-shadow-root"><span class="typ">ShadowRoot</span></a><span class="pln"> </span><span class="pun">:</span><span class="pln"> </span><a href="http://www.w3.org/TR/domcore/#interface-documentfragment"><span class="typ">DocumentFragment</span></a><span class="pln"> </span><span class="pun">{</span><span class="pln">
    </span><a href="http://www.w3.org/TR/domcore/#element"><span class="typ">Element</span></a><span class="pln"> </span><a href="http://www.w3.org/TR/shadow-dom/#api-shadow-root-get-element-by-id"><span class="pln">getElementById</span></a><span class="pun">(</span><span class="kwd">in</span><span class="pln"> </span><span class="typ">DOMString</span><span class="pln"> elementId</span><span class="pun">);</span><span class="pln">
    </span><a href="http://www.w3.org/TR/domcore/#nodelist"><span class="typ">NodeList</span></a><span class="pln"> </span><a href="http://www.w3.org/TR/shadow-dom/#api-shadow-root-get-elements-by-class-name"><span class="pln">getElementsByClassName</span></a><span class="pun">(</span><span class="kwd">in</span><span class="pln"> </span><span class="typ">DOMString</span><span class="pln"> tagName</span><span class="pun">);</span><span class="pln">
    </span><a href="http://www.w3.org/TR/domcore/#nodelist"><span class="typ">NodeList</span></a><span class="pln"> </span><a href="http://www.w3.org/TR/shadow-dom/#api-shadow-root-get-elements-by-tag-name"><span class="pln">getElementsByTagName</span></a><span class="pun">(</span><span class="kwd">in</span><span class="pln"> </span><span class="typ">DOMString</span><span class="pln"> className</span><span class="pun">);</span><span class="pln">
    </span><a href="http://www.w3.org/TR/domcore/#nodelist"><span class="typ">NodeList</span></a><span class="pln"> </span><a href="http://www.w3.org/TR/shadow-dom/#api-shadow-root-get-elements-by-tag-name-ns"><span class="pln">getElementsByTagNameNS</span></a><span class="pun">(</span><span class="typ">DOMString</span><span class="pln"> </span><span class="kwd">namespace</span><span class="pun">,</span><span class="pln"> </span><span class="typ">DOMString</span><span class="pln"> localName</span><span class="pun">);</span><span class="pln">
    attribute </span><span class="kwd">bool</span><span class="pln"> </span><a href="http://www.w3.org/TR/shadow-dom/#api-shadow-root-apply-author-styles"><span class="pln">applyAuthorStyles</span></a><span class="pun">;</span><span class="pln">
    attribute </span><span class="kwd">bool</span><span class="pln"> </span><a href="http://www.w3.org/TR/shadow-dom/#api-shadow-root-reset-style-inheritance"><span class="pln">resetStyleInheritance</span></a><span class="pun">;</span><span class="pln">
    </span><span class="kwd">readonly</span><span class="pln"> attribute </span><span class="typ">Element</span><span class="pln"> </span><a href="http://www.w3.org/TR/shadow-dom/#api-shadow-root-active-element"><span class="pln">activeElement</span></a><span class="pun">;</span><span class="pln">
    </span><span class="kwd">readonly</span><span class="pln"> attribute </span><a href="http://dvcs.w3.org/hg/editing/raw-file/tip/editing.html#selection"><span class="typ">Selection</span></a><span class="pln"> </span><a href="http://www.w3.org/TR/shadow-dom/#api-shadow-root-selection"><span class="pln">selection</span></a><span class="pun">;</span><span class="pln">
    attribute </span><span class="typ">DOMString</span><span class="pln"> </span><a href="http://www.w3.org/TR/shadow-dom/#api-shadow-root-inner-html"><span class="pln">innerHTML</span></a><span class="pun">;</span><span class="pln">
</span><span class="pun">}</span><span class="pln">
</span><span class="typ">ShadowRoot</span><span class="pln"> </span><span class="kwd">implements</span><span class="pln"> </span><a href="http://dev.w3.org/2006/webapi/selectors-api/#nodeselector"><span class="typ">NodeSelector</span></a><span class="pun">;</span></code></pre>

<h2 id="appendix-b-html-elements">Appendix B. HTML Elements</h2>

<dl>
<dt><code><a href="http://www.w3.org/TR/shadow-dom/#content-element">&lt;content&gt;</a></code></dt>
<dd>
    <p>Represents an <a href="http://www.w3.org/TR/shadow-dom/#dfn-insertion-point">insertion point</a> in a <a href="http://www.w3.org/TR/shadow-dom/#dfn-shadow-dom-subtree">shadow DOM subtree</a>. The <a href="http://www.w3.org/TR/shadow-dom/#dfn-insertion-point">insertion point</a> is replaced with the elements' children at rendering time. The <code><a href="http://www.w3.org/TR/shadow-dom/#content-element">&lt;content&gt;</a></code> element itself is never rendered.</p>
    <p>Context: Where <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/elements.html#flow-content-0">flow content</a> is expected.</p>
    <p>Children: anything (fallback content)</p>
    <p>Attributes:</p>
    <p><code>select</code>—the value is a list of <a href="http://www.w3.org/TR/shadow-dom/#dfn-selector-fragment">selector fragments</a>, addressing immediate children of the element.</p>
<!--    <p><code>apply-shadow-styles</code>&mdash;if <code>true</code>, the styles of the shadow DOM tree apply to the element children, rendered in place of the <code>&lt;content&gt;</code> element. if <code>false</code> (default), the styles of the shadow DOM tree do not apply. -->
</dd>
<dt><code>&lt;decorator&gt;</code></dt>
<dd>
    <p>Defines a new decorator. Typically, you would also give it an id attribute to make it addressable from CSS.
    </p><p>Context: anywhere in the document.
    </p><p>Children: <code>&lt;template&gt;</code> and <code>&lt;script&gt;</code>
    </p><p>Attributes:
    </p><p><code>apply-author-styles</code>—if <code>true</code>, the author styles of the document apply to the <a href="http://www.w3.org/TR/shadow-dom/#dfn-shadow-dom-subtree">shadow DOM subtree</a> of the element. If <code>false</code> (default), the author styles do not apply.
</p></dd>
<dt><code>&lt;element&gt;</code></dt>
<dd>
    <p>Defines a new custom element.
    </p><p>Context: anywhere in the document.
    </p><p>Children: <code>&lt;template&gt;</code> and <code>&lt;script&gt;</code>
    </p><p>Attributes:
    </p><p><code>constructor</code>—name of the generated constructor function. If specified, a key by this name is added to the <code>window</code> object, referring to the element's generated constructor.
    </p><p><code>extends</code>—tag name of the element or a defined custom element constructor name that the new custom element extends.
    </p><p><code>name</code>—the name of the custom element constructor that is generated by this definition.
    </p><p><code>apply-author-styles</code>—if <code>true</code>, the author styles of the document apply to the <a href="http://www.w3.org/TR/shadow-dom/#dfn-shadow-dom-subtree">shadow DOM subtree</a> of the element. If <code>false</code> (default), the author styles do not apply.
</p></dd>
<dt><code><a href="http://www.w3.org/TR/shadow-dom/#shadow-element">&lt;shadow&gt;</a></code></dt>
<dd>
    <p>Specifies a <a href="http://www.w3.org/TR/shadow-dom/#dfn-shadow-insertion-point">shadow insertion point</a>, where the older <a href="http://www.w3.org/TR/shadow-dom/#dfn-shadow-dom-subtree">shadow DOM subtree</a> in element's shadow DOM <a href="http://www.w3.org/TR/shadow-dom/#dfn-tree-stack">tree stack</a> is rendered. The <code><a href="http://www.w3.org/TR/shadow-dom/#shadow-element">&lt;shadow&gt;</a></code> element itself is never rendered.</p>
    <p>Context: Where <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/elements.html#flow-content-0">flow content</a> is expected.</p>
    <p>Children: anything (fallback content).</p>
</dd>
<dt><code>&lt;template&gt;</code></dt>
<dd>
    <p>Defines an inert chunk of DOM that can then be used for creating DOM instances in an unknown parsing context.
    </p><p>Context: anywhere in the document.
    </p><p>Children: any element.
</p></dd>
</dl>

<h2 id="appendix-c-custom-element-constructor-properties">Appendix C. Custom Element Constructor Properties</h2>

<p>Here are some more properties of the generated constructor and FancyButton instances:</p>

<pre class="prettyprint"><code><span class="pln">
</span><span class="kwd">typeof</span><span class="pln"> </span><span class="typ">FancyButton</span><span class="pln"> </span><span class="pun">⇒</span><span class="pln"> </span><span class="str">"function"</span><span class="pln">
</span><span class="typ">FancyButton</span><span class="pun">.</span><span class="pln">call</span><span class="pun">({})</span><span class="pln"> </span><span class="pun">⇒</span><span class="pln"> </span><span class="kwd">throws</span><span class="pln">
</span><span class="typ">Object</span><span class="pun">.</span><span class="pln">getPrototypeOf</span><span class="pun">(</span><span class="typ">FancyButton</span><span class="pun">.</span><span class="pln">prototype</span><span class="pun">)</span><span class="pln"> </span><span class="pun">===</span><span class="pln">
   </span><span class="typ">HTMLButtonElement</span><span class="pun">.</span><span class="pln">prototype </span><span class="pun">⇒</span><span class="pln"> </span><span class="kwd">true</span><span class="pln">

document</span><span class="pun">.</span><span class="pln">body</span><span class="pun">.</span><span class="pln">lastChild </span><span class="pun">===</span><span class="pln"> b </span><span class="pun">⇒</span><span class="pln"> </span><span class="kwd">true</span><span class="pln">
b</span><span class="pun">.</span><span class="pln">tagName </span><span class="pun">⇒</span><span class="pln"> </span><span class="str">"button"</span><span class="pln">
b</span><span class="pun">.</span><span class="pln">outerHTML </span><span class="pun">⇒</span><span class="pln"> </span><span class="str">"&lt;button is="</span><span class="typ">FancyButton</span><span class="str">"&gt;&lt;/button.html&gt;"</span><span class="pln">
b </span><span class="kwd">instanceof</span><span class="pln"> </span><span class="typ">FancyButton</span><span class="pln"> </span><span class="pun">⇒</span><span class="pln"> </span><span class="kwd">true</span><span class="pln">
b </span><span class="kwd">instanceof</span><span class="pln"> </span><span class="typ">HTMLButtonElement</span><span class="pln"> </span><span class="pun">⇒</span><span class="pln"> </span><span class="kwd">true</span></code></pre>

<h2 id="acknowledgements">Acknowledgements</h2>

<p>Thanks to <span class="vcard">Alex Komoroske</span>, <span class="vcard">Alex Russell</span>, <span class="vcard">Darin Fisher</span>, <span class="vcard">Dirk Pranke</span>, <span class="vcard">Divya Manian</span>, <span class="vcard">Erik Arvidsson</span>, <span class="vcard">Hayato Ito</span>, <span class="vcard">Hajime Morita</span>, <span class="vcard">Ian Hickson</span>, <span class="vcard">Jonas Sicking</span>, <span class="vcard">Rafael Weinstein</span>, <span class="vcard">Roland Steiner</span>, and <span class="vcard">Tab Atkins</span> for their comments and contributions to this document.</p>



</body></html>